#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
#include <string>
#include <random>
// 关于这个超时锁的应用暂时还每想到
class ATM
{
private:
    std::timed_mutex operationMutex;
    double balance;
    std::string atmId;

public:
    ATM(const std::string &id, double initialBalance)
        : atmId(id), balance(initialBalance) {}

    bool withdrawMoney(const std::string &userId, double amount)
    {
        // 设置操作超时时间为3秒
        std::chrono::seconds timeout(2);

        // 尝试获取ATM操作权限
        if (!operationMutex.try_lock_for(timeout))
        {
            std::cout << "用户 " << userId << " 在ATM " << atmId
                      << " 等待超时，请尝试其他ATM机或稍后再试\n";
            return false;
        }

        // 模拟取款操作耗时
        std::cout << "用户 " << userId << " 正在ATM " << atmId << " 操作...\n";

        // 随机模拟网络延迟
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> delay(100, 2000);
        std::this_thread::sleep_for(std::chrono::milliseconds(delay(gen)));

        // 检查余额和执行取款
        if (balance >= amount)
        {
            balance -= amount;
            std::cout << "用户 " << userId << " 成功从ATM " << atmId
                      << " 取出 " << amount << " 元\n";
            std::cout << "ATM " << atmId << " 剩余余额: " << balance << " 元\n";
            operationMutex.unlock();
            return true;
        }
        else
        {
            std::cout << "ATM " << atmId << " 余额不足，取款失败\n";
            operationMutex.unlock();
            return false;
        }
    }
};

void customerOperation(ATM &atm, const std::string &userId, double amount)
{
    // 模拟客户到达时间随机性
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_int_distribution<> arrival(100, 1000);
    std::this_thread::sleep_for(std::chrono::milliseconds(arrival(gen)));

    std::cout << "用户 " << userId << " 开始尝试取款...\n";
    bool success = atm.withdrawMoney(userId, amount);

    if (!success)
    {
        std::cout << "用户 " << userId << " 取款失败，准备前往其他ATM机\n";
    }
}

int main()
{
    // 创建一个ATM机，初始余额100000元
    ATM atm("ATM001", 100000);

    // 模拟多个客户同时使用ATM
    std::thread customer1(customerOperation, std::ref(atm), "张三", 2000);
    std::thread customer2(customerOperation, std::ref(atm), "李四", 3000);
    std::thread customer3(customerOperation, std::ref(atm), "王五", 1500);
    std::thread customer4(customerOperation, std::ref(atm), "赵六", 4000);

    customer1.join();
    customer2.join();
    customer3.join();
    customer4.join();

    return 0;
}